/**
 * 
 */
package edu.umd.clip.lm.model.training;

import java.util.*;

import edu.umd.clip.lm.model.HistoryTreePayload;
import edu.umd.clip.lm.questions.Question;
import edu.umd.clip.lm.util.tree.*;

/**
 * @author Denis Filimonov <den@cs.umd.edu>
 *
 */
public class HistoryTreeLayer {
	final int number;
	final ArrayList<BinaryTree<HistoryTreePayload>> nodes;

	public HistoryTreeLayer(BinaryTree<HistoryTreePayload> root) {
		this.nodes = new ArrayList<BinaryTree<HistoryTreePayload>>(1);
		this.nodes.add(root);
		this.number = 0;
	}
	
	public static HistoryTreeLayer getLayer(BinaryTree<HistoryTreePayload> root, int number) {
		HistoryTreeLayer layer = new HistoryTreeLayer(root);
		while(layer.number < number) {
			layer = layer.getNext();
		}
		
		return layer;
	}
	
	private HistoryTreeLayer(ArrayList<BinaryTree<HistoryTreePayload>> nodes, int number) {
		this.nodes = nodes;
		this.number = number;
	}
	
	public HistoryTreeLayer getNext() {
		ArrayList<BinaryTree<HistoryTreePayload>> newNodes = new ArrayList<BinaryTree<HistoryTreePayload>>(nodes.size());
		for(BinaryTree<HistoryTreePayload> node : nodes) {
			if (!node.isLeaf()) {
				BinaryTree<HistoryTreePayload> left = node.getLeft();
				BinaryTree<HistoryTreePayload> right = node.getRight();
				
				if (node.getPayload().question.getQuestionType() == Question.IN_SET_QUESTION && left.getPayload().isBackoff) {
					newNodes.add(left.getRight());
				} else {
					newNodes.add(left);
				}
				newNodes.add(right);
			}
		}
		
		return new HistoryTreeLayer(newNodes, number+1);
	}

	public int getNumber() {
		return number;
	}

	public List<BinaryTree<HistoryTreePayload>> getNodes() {
		return nodes;
	}
	
}
